/**
 * 
 */
package org.mediahouse.trac;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.mediahouse.trac.http.AbstractCustomHttpServlet;
import org.mediahouse.trac.util.Random;
import org.mediahouse.trac.util.SimpleTextHtmlWriter;
import org.mediahouse.trac.util.debug;

import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

/**
 * @author Tin
 * @version %I%, %G%
 * 
 */
@SuppressWarnings("serial")
public class LoginManager extends AbstractCustomHttpServlet {

    /**
     * {@inheritDoc}
     * 
     * @see org.mediahouse.trac.http.AbstractCustomHttpServlet#doRequest(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse,
     *      org.mediahouse.trac.http.CustomHttpServlet.HttpRequestMethodType)
     */
    @Override
    public void doRequest(final HttpServletRequest req,
            final HttpServletResponse resp, final HttpRequestMethodType method)
            throws Exception {

        final UserService userService = UserServiceFactory.getUserService();
        debug.trace("Is user logged in?", userService.isUserLoggedIn());

        class WebSecurityService {
            public String parse(final String in) {
                final String out = in.toString();
                return out;
            }
        }

        final WebSecurityService security = new WebSecurityService();
        final HttpSession session = req.getSession();
        switch (method) {

        /**
         * This {@code HttpServlet} class responds to all {@code GET} and
         * {@code POST} requests, and ignores any {@code PUT} or {@code DELETE}
         * HTTP request method types.
         */
        case GET:
            if (session.getAttribute("token") != null) redirect("/", resp);
            else {
                resp.setContentType("text/html");
                final SimpleTextHtmlWriter html = new SimpleTextHtmlWriter(resp.getWriter());
                try {
                    resp.setStatus(HttpServletResponse.SC_OK);
                    html.openForm(req.getServletPath(), HttpRequestMethodType.POST);
                    html.input("username", "text", string.empty).submit("login");
                    html.closeForm();
                } finally {
                    html.close();
                }
            }
            break;

        /**
         * {@code POST} requests to the LoginManager are specifically diverted
         * to the login 'submit' request handler. Requests forwarded to this
         * handler are expected to carry authentication information.
         */
        case POST:
            final String requestedUsername = security.parse(req.getParameter("username"));
            boolean ok = true;
            if (!authenticated(requestedUsername)) ok = false;
            if (ok) {
                session.setAttribute("token", Random.newSecureUid());
                session.setAttribute("name", requestedUsername);
                redirect("/", resp);
            } else redirect(req.getServletPath(), resp);
            break;
        }
    }

    /**
     * @param requestedUsername
     *            the requested user-name
     * @return {@code true} <em>if and only if</em> the requested user-name is a
     *         string of acceptable characters with length greater than 3;
     *         {@code false} otherwise
     */
    private boolean authenticated(final String requestedUsername) {
        // TODO implement proper persistent user/roles authentication
        return requestedUsername != null && requestedUsername.length() >= 3;
    }

    /**
     * @author Tin
     * @version %I%, %G%
     * 
     */
    public interface string {

        /**
         * A declared representation of the empty string <span><code>""</code>
         * .</span>
         */
        public static final String empty = "";

    }

}
